package modules.exports;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import core.GroupeNotes;
import core.Mesure;
import core.Note;
import core.Partition;
import core.Section;

/**
 * @author Guillaume Anne
 * Ce module permet d'exporter des partitions dans un format xml utilise par le logiciel XMLDrumer
 * 
 * ATTENTION : Ce format n'a aucun rapport avec le musicXML si ce n'est l'utilisation du format xml :
 * - La syntaxe est differente
 * - L'usage est different
 * A bon entendeur
 */
public class ExportXMLDrumer {
	
	private static int VALEUR_DU_TIRET = 24;
	private static int tempsVoieBasse = 0;
	private static int tempsVoieHaute = 0; 
	private static double timelaps = 0;
	private static BufferedWriter buffer;
	private static double tempo;

	/**
	 * Methode generale permettant d'exporter une partition au format interne vers un fichier XML Drummer
	 * 
	 * @param partition : Une partition au format interne
	 * @param emplacementFichierExport : l'emplacement du fichier de sortie
	 * @param args : Une serie d'arguments dependant du type d'export, ici les delais necessaire avant de jouer les notes et la musique
	 * @throws IOException
	 */
	public static void exporter(Partition partition, String emplacementFichierExport, String[] args) throws IOException
	{		
		double tempo = partition.getTempo();
		buffer = new BufferedWriter(new FileWriter(emplacementFichierExport));
		
		// Definition classique d'un contenu de type xml
		buffer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
		buffer.newLine();
		
		// Entete de la partition : la balise root
		buffer.write("<root name=\"" + partition.getTitre() + "\" tempo=\"" + tempo + "\" delayNote=\"" + args[0] + "\" delayMusique=\"" + args[1] +  "\">");
		buffer.newLine();
		
		// Pour chaque section de la partition
		for(Section section : partition.getSection())
		{
			// Definition de la section : balise section
			buffer.write("\t<section name=\"" + section.getName() + "\" temps=\"" + tempsVoieBasse/VALEUR_DU_TIRET + "\" tempo=\"" + tempo +  "\" start=\"" + arrondir(timelaps/VALEUR_DU_TIRET,2) + "\">");
			buffer.newLine();
			
			// Pour chaque mesure
			for(Mesure mesure : section.getMesure())
			{
				// Les mesure ne sont pas traitees dans le format XML Drummer
				// Pour chaque groupe de note (ensembles de notes a un temps T) de la mesure
				for(GroupeNotes groupeNotes : mesure.getGroupeNote())
				{
					gererGroupeNote(groupeNotes);
				}
			}
			// On cloture la section
			buffer.write("\t</section>");
			buffer.newLine();
		}
		
		// On cloture la partition
		buffer.write("</root>");
		buffer.newLine();
		buffer.close();
	}
	
	private static void gererGroupeNote(GroupeNotes groupeNotes) throws IOException{
		// On masque les silences
		if(groupeNotes.getNotes().get(0).getLabel() != "Silence")
		{
			buffer.write("\t\t<notes temps=\"" + tempsVoieBasse/VALEUR_DU_TIRET + "\">");
			buffer.newLine();
			// Les groupe de notes ne sont pas traitees dans le format XML Drummer
			// Pour chaque note
			for(Note note : groupeNotes.getNotes())
			{
				// On imprime tout ce qui est different d'un silence
				buffer.write("\t\t\t<"+note.getLabel()+"/>");
				buffer.newLine();
			}
			buffer.write("\t\t</notes>");
			buffer.newLine();
		}
		if(groupeNotes.getVoie()==1)
			tempsVoieHaute += groupeNotes.getDuree();
		else
			tempsVoieBasse += groupeNotes.getDuree();

		timelaps += groupeNotes.getDuree() * tempo;
	}
	
	public static double arrondir(double value, int n) { 
		double r = (Math.round(value * Math.pow(10, n))) / (Math.pow(10, n)); 
		return r; 
	}
}
